//
//  HYVideoRoomViewController.m
//  HYVideoPlayer
//
//  Created by liguoqing on 2023/7/21.
//

#import "HYVideoRoomViewController.h"
#import <HYUIKit/YCCycleScrollView.h>
#import <HYVideoPlayer/HYVideoPlayerConfigure.h>
#import <HYVideoPlayer/HYVideoSliderToolView.h>
#import <HYVideoPlayer/HYVideoPlayerTopView.h>
#import <HYVideoPlayer/HYPlayerSpeedView.h>
#import <HYVideoPlayer/HYVideoSpeedBottomView.h>
#import <HYVideoPlayer/HYVideoLockView.h>
#import <HYVideoPlayer/PictureInPictureManager.h>
#import <HYVideoPlayer/PSSearchViewController.h>
#import <HYVideoPlayer/PSCoverView.h>
#import <HYUIKit/HYMenuScrollView.h>
#import <HYDLNA/HYDLNA.h>
#import <HYUtls/UIMacro.h>
#import <HYUIKit/HYMenuScrollView.h>
#import <HYNetStatus/HYNetWorkManager.h>
#import <HYVideoPlayer/HYVideoScreenShotShareView.h>
#import <MediaPlayer/MediaPlayer.h>
#import <Photos/Photos.h>
#import <HYUIKit/HYAlertShowAnimate.h>
#import "HYShowQRCodeView.h"
#import "HYActivity.h"
#import <Social/Social.h>
#import "HYVideoViewModel.h"
#import "HYFileDownloadView.h"
#import "HYPreviewHistoryManager.h"
#import "HYAudioSuspensionView.h"
#import "HYVideoListView.h"
#import "HYSimplePlayerGuideView.h"

@interface HYVideoRoomViewController ()<HYPlayerHandlerProtocol,HY_Auto_Rotate_Delegate,HYVideoListViewDelegate>
/// viewModel
@property (nonatomic, strong) HYVideoViewModel *viewModel;
/// 视频配置信息
@property (nonatomic, strong) HYVideoPlayerConfig *config;
/// 滚动视图
@property (nonatomic, strong) YCCycleScrollView *mainScorllView;
/// 竖屏底部工具栏
@property (nonatomic, strong) HYVideoSliderToolView *minBottomView;
/// 全屏按钮
@property (nonatomic, strong) UIButton *fullButton;
/// 横屏顶部工具栏
@property (nonatomic, strong) HYVideoPlayerTopView *topToolBar;
/// 竖屏倍速
@property (nonatomic, strong) HYVideoSpeedBottomView *speedBottomView;
/// 倍速视图
@property (nonatomic, strong) HYPlayerSpeedView *speedView;
/// 截屏按钮
@property (nonatomic, strong) UIButton *cutScreenButton;
/// 锁屏button
@property (nonatomic, strong) UIButton *lockButton;
/// 画中画黑色背景view
@property (nonatomic, strong) UIView *pipBgView;
/// 播放timer
@property (nonatomic,strong) NSTimer *playTimer;
/// 是否已经开启投屏
@property (nonatomic, assign) BOOL isStartPs;
/// 隐藏菜单定时器
@property (nonatomic, assign) NSInteger hiddMeunTime;
/// 是否已经开启画中画
@property (nonatomic, assign) BOOL isOpenPip;
/// 外界调用直接锁屏(禁止转屏)
@property (nonatomic, assign) BOOL isLocked;
/// 投屏设备
@property (nonatomic, strong) CLUPnPDevice *device;
/// 投屏遮罩
@property (nonatomic, strong) PSCoverView *psCoverView;
/// 内容
@property (nonatomic, strong) HYMenuScrollView *hToolView;
/// 分享视频
@property (nonatomic, strong) HYVideoScreenShotShareView *shareView;
// airplay
@property (nonatomic, strong) MPVolumeView *volumView;
/// 是否开启airPlay
@property (nonatomic, assign) BOOL isAirPlay;
/// 目录
@property (nonatomic, strong) HYVideoListView *listView;
// 状态栏类型
@property (nonatomic, assign) UIStatusBarStyle statusBarStyle;
// 小视频引导手势
@property (nonatomic, strong) HYSimplePlayerGuideView *guideView;

@end

@implementation HYVideoRoomViewController

- (void)dealloc
{
    CLog(@"dealloc -- %@",[self class]);
}

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
    return UIStatusBarAnimationFade;
}

#pragma mark - 隐藏底部白边
- (BOOL)prefersHomeIndicatorAutoHidden
{
    return self.bottomToolBar.hidden;
}

- (instancetype)initWithViewModel:(HYVideoViewModel *)viewModel
{
    self = [super init];
    if(self){
        self.viewModel = viewModel;
        self.config = viewModel.videoConfig;
        [self bindPlaySignal];
    }
    return self;
}

- (instancetype)initWithConfig:(HYVideoPlayerConfig *)config
{
    self = [super init];
    if(self){
        self.config = config;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [HYAudioSuspensionView close];
    [PictureInPictureManager closePip];
    self.hy_autoRotate = YES;
    self.navigationController.navigationBar.inputView.hidden = YES;
    self.view.backgroundColor = [UIColor blackColor];
    [self addMiniView];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    if(!self.config.isAudioMode){
        self.statusBarStyle = [UIApplication sharedApplication].statusBarStyle;
        [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
    }
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    if([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    }
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    if([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
    };
    if(!self.config.isAudioMode){
        [UIApplication sharedApplication].statusBarStyle = self.statusBarStyle;
    }
}

- (void)bindPlaySignal
{
    @weakify(self);
    [self.viewModel.playSubject subscribeNext:^(NSString *videoUrl) {
        @strongify(self);
        if(videoUrl.length){
            if(self.isStartPs){
                [[HYDLNA sharedHYDLNAManager] playTheURL:videoUrl];
            }else{
                self.playerManager.currentVideoUrl = videoUrl;
            }
        }
    }];
}

- (void)addMiniView
{
    self.view.backgroundColor = kBlackColor;
    [self addPlayerView];
    [self addVideoToolBar];
    [self addPlayerObserver];
}
- (void)addPlayerView
{
    if(self.config.isAudioMode){
        [self.view addSubview:self.playerManager.playerView];
        [self.playerManager.playerView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.view);
        }];
    }else{
        [self addScrollViewPlayView];
    }
    [self registerNotification];
}


- (void)addScrollViewPlayView
{
    [self.playerManager.playerView setSlidingColor:APPMainThemeColor];
    YCCycleScrollView *mainScorllView = [[YCCycleScrollView alloc] initWithFrameInVertical:CGRectMake(0, 0, kMainScreenWidth, kMainScreenHeight)];
    if (@available(iOS 11.0, *)) {
        mainScorllView.mainScrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
    mainScorllView.backgroundColor = [UIColor whiteColor];
    @weakify(self,mainScorllView);
    mainScorllView.mainScrollView.scrollEnabled = YES;
    [mainScorllView fetchShowView:^UIView *(NSInteger page) {
        @strongify(self,mainScorllView);
        UIView *contentView  = [[UIView alloc]initWithFrame:mainScorllView.bounds];
        contentView.tag = page;
        contentView.backgroundColor = UIColor.blackColor;
        UIImageView *coverView = [[UIImageView alloc]init];
        coverView.tag = 1000;
        coverView.contentMode = UIViewContentModeScaleAspectFit;
        coverView.opaque = NO;
        coverView.image = [self.config fetchCurrentVideoImageIndex:page];
        [contentView addSubview:coverView];
        [coverView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(contentView);
        }];
        return contentView;
    }];
    
    mainScorllView.endLastBlock = ^{
        [HYHub showMessage:NSLocalizedString(@"全部播放完成", nil)];
    };
    [self.view insertSubview:mainScorllView atIndex:0];
    mainScorllView.notCycle = YES;
    mainScorllView.totalNumber = self.config.videoSoucres.count;
    mainScorllView.isNotCache = YES;
    mainScorllView.curPage = self.config.playIndex;
    self.mainScorllView = mainScorllView;
    
    NSInteger add = 0;
    if(self.playerManager.player.normalPlaying){
        UIView *cView = [self.mainScorllView getCurrentShowView];
        if(cView){
            UIImageView *coverView = [cView viewWithTag:1000];
            coverView.hidden = self.playerManager.player.normalPlaying;
            [cView addSubview:self.playerManager.playerView];
            [self.playerManager.playerView mas_remakeConstraints:^(MASConstraintMaker *make) {
                make.edges.mas_equalTo(0);
            }];
            add = 1;
        }
    }
    __block BOOL isNeedSave = NO;
    [[[RACObserve(mainScorllView, curPage) distinctUntilChanged] skip:add] subscribeNext:^(id x) {
        @strongify(self);
        if(isNeedSave){
            [self savePlayRecord];
        }
        isNeedSave = YES;
        [self changeIndex:NO];
    }];
}

- (void)changeIndex:(BOOL)ready
{
    [self.playerManager.playerView removeFromSuperview];
    
    UIView *contentView = [self.mainScorllView getCurrentShowView];
    UIImageView *coverView = [contentView viewWithTag:1000];
    coverView.hidden = NO;
    [contentView insertSubview:self.playerManager.playerView atIndex:0];
    [self.playerManager.playerView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(0);
    }];
    [self.viewModel changePlayIndex:self.mainScorllView.curPage];
}

- (void)addVideoToolBar
{
    [self addVerticalContentView];
    [self addFullTopToolBar:HYVPTNV_TYPE_NORMAL];
    [self addFullScreenBottomToolBar:self.config.videoSoucres.count>1?HYVPBNV_TYPE_DIRECTORY:HYVPBNV_TYPE_NORMAL];
    [self addFullContentView];
    [self bindPlayerSignal];
    if(self.config.isAudioMode){
        [self autoPlay];
    }else{
        [self showGuideView];
    }
}

- (void)addVerticalContentView
{
    @weakify(self);
    HYVideoSliderToolView *bottomView = [[HYVideoSliderToolView alloc]init];
    bottomView.hidden = YES;
    [self.view addSubview:bottomView];
    [bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.mas_offset(0);
        make.bottom.mas_equalTo(0);
        make.height.mas_equalTo(74+HOME_BAR_HEIGHT);
    }];
    self.minBottomView = bottomView;
    
    self.minBottomView.fullButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        [self fullBtnAction];
        return [RACSignal empty];
    }];
}

/// 添加横屏底部部工具栏
- (void)addFullTopToolBar:(HYVideoPlayerTopView_ShowType)topType
{
    self.topToolBar = [[HYVideoPlayerTopView alloc]initView:topType];
    self.topToolBar.titleLabel.text = [self.config fetchCurrentVideoTitle];
    [self.view addSubview:self.topToolBar];
    [self.topToolBar mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(0);
        make.left.right.mas_equalTo(0);
        make.height.mas_equalTo(68+STATUS_BAR_HEIGHT);
    }];
    @weakify(self);
    self.topToolBar.backButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        if(![self isFull]){
            [self minBackBtnAction];
        }else{
            [self fullShowVideo:NO];
        }
        return [RACSignal empty];
    }];
    self.topToolBar.pipButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        [self startPip];
        return [RACSignal empty];
    }];
    self.topToolBar.psButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        [self waitBackMin:^{
            @strongify(self);
            [self startToSearchDevice];
        }];
        return [RACSignal empty];
    }];
    self.topToolBar.psButton.hidden = !self.config.isSupportProjectionScreen;
    [RACObserve(self.topToolBar, hidden) subscribeNext:^(id x) {
        @strongify(self);
        self.hiddMeunTime = 0;
    }];
    // 如果是网络视频则采用系统的airplay
    if(!self.config.isSupportProjectionScreen){
        // 投屏
        self.volumView = [[MPVolumeView alloc]init];
        self.volumView.showsVolumeSlider = NO;
        [self.volumView setRouteButtonImage:[UIImage imageNamed:@"icon_video_airplay"] forState:UIControlStateNormal];
        [self.topToolBar addSubview:self.volumView];
        [self.volumView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.topToolBar.psButton);
        }];
        NSString *airplayDeviceName = [self activeAirplayOutputRouteName];
        if(self.volumView.wirelessRouteActive && airplayDeviceName.length){// airplay 投屏中
            [self.playerManager.playerView showTipView:NSLocalizedString(@"airPlay投屏中", nil) delay:0];
        }
    }
}

- (void)addFullScreenBottomToolBar:(HYVideoPlayerBottomView_ShowType)bottomType
{
    self.bottomToolBar = [[HYVideoPlayerBottomView alloc]initView:bottomType];
    self.bottomToolBar.hidden = YES;
    [self.view addSubview:self.bottomToolBar];
    [self.bottomToolBar mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.left.right.mas_equalTo(0);
        make.height.mas_equalTo(BOTTOM_HEIGHT);
    }];
    self.bottomToolBar.screen = self.playerManager.videoGravity;
    RAC(self.playerManager,videoGravity) = [RACObserve(self.bottomToolBar, screen)skip:1];
    
    @weakify(self);
    self.bottomToolBar.playButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(UIButton *x) {
        @strongify(self);
        x.selected = !x.selected;
        if(x.selected){
            [self.playerManager play];
        }else{
            [self.playerManager pause];
        }
        return [RACSignal empty];
    }];
    self.bottomToolBar.lastButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        [self playLastVideo];
        return [RACSignal empty];
    }];
    self.bottomToolBar.nextButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        [self playNextVideo:NO];
        return [RACSignal empty];
    }];
    self.bottomToolBar.backMinButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        [self fullShowVideo:NO];
        return [RACSignal empty];
    }];
    self.bottomToolBar.speedButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        if(self.playerManager.player.normalPlaying){
            [self menuViewHidden:NO];
            if([self isFull]){
                [self.speedView showView];
            }else{
                [self.speedBottomView show];
            }
        }
        return [RACSignal empty];
    }];
    self.bottomToolBar.catalogButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        [self showVideoList];
        return [RACSignal empty];
    }];
    self.bottomToolBar.qrButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        [self showQrCodeImage];
        return [RACSignal empty];
    }];
    self.bottomToolBar.downloadButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        if([self.config isLocalVideo]){
            [HYHub showMessage:NSLocalizedString(@"已缓存",nil)];
        }else{
            [self.viewModel startDownloadBlock:^(NSString *result){
                HYFileDownloadView *downloadView = [[HYFileDownloadView alloc]initWithFolderIdentificaiton:result
                                                                                                    isFull:[self isFull]
                                                                                                 disappear:nil];
                [downloadView show];
            }];
        }
        return [RACSignal empty];
    }];
    self.bottomToolBar.collectButton.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        @strongify(self);
        [self.viewModel collectVideo];
        return [RACSignal empty];
    }];
    
    [self.bottomToolBar jumpTime:^(NSInteger time) {
        @strongify(self);
        if(self.isStartPs){
            [[HYDLNA sharedHYDLNAManager] seekChanged:time];
        }else{
            [self.playerManager assignTimePlay:time];
        }
    }];
    
    /// 横屏工具栏隐藏后显示底部进度条
    HYVideoPlayerProressSlider *slider = [[HYVideoPlayerProressSlider alloc]init];
    //加载self.playerView上，以免锁屏对此有影响
    [self.playerManager.playerView addSubview:slider];
    if (iPhoneX) {
        [slider mas_makeConstraints:^(MASConstraintMaker *make) {
            make.bottom.mas_equalTo(0);
            make.height.mas_equalTo(5);
            make.left.mas_equalTo(STATUS_BAR_HEIGHT);
            make.right.mas_equalTo(-STATUS_BAR_HEIGHT);
        }];
    } else {
        [slider mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.bottom.right.mas_equalTo(0);
            make.height.mas_equalTo(5);
        }];
    }
    slider.slider.thumbImage = nil;
    slider.userInteractionEnabled = NO;
    RAC(slider, cache) = RACObserve(self.bottomToolBar.slider, cache);
    RAC(slider.slider, progress) = RACObserve(self.bottomToolBar.slider.slider, progress);
    RAC(slider, hidden) = [[[[RACObserve(self.bottomToolBar, hidden) filter:^BOOL(id value) {
        @strongify(self);
        return !self.view.hidden;
    }] merge:[RACObserve(self.view, hidden) not]] not] map:^id(id value) {
        @strongify(self);
        if(![self isFull]){
            return @(YES);
        }
        if (@available(iOS 11.0, *)) {
            //延迟一秒执行是因为在全屏显示出bottom时，会自动先显示出来，在调用一次显示，体验有问题。
            [[[[[RACSignal interval:1 onScheduler:[RACScheduler currentScheduler]]
                take:1] takeUntil:[RACObserve(self.bottomToolBar, hidden) skip:1]]
              takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) {
                @strongify(self);
                [self setNeedsUpdateOfHomeIndicatorAutoHidden];
            }];
        }
        if (![value boolValue]) {
            @strongify(self);
            return @(!(self.bottomToolBar.hidden && !self.view.hidden));
        }
        return value;
    }];
}

/// 添加横屏按钮
- (void)addFullContentView
{
    /// 锁屏按钮
    UIView *lockView = [HYVideoLockView addLockView:self.view
                                         followView:self.topToolBar
                                             unlock:HY_IMAGE_URL(@"icon_screen_unlock")
                                               lock:HY_IMAGE_URL(@"icon_screen_lock")
                                         lockMargin:-15];
    [HYVideoLockView setFilterNoHiddenView:self.mainScorllView];
    [lockView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.view.mas_centerY).offset(-10);
    }];
    self.lockButton = (UIButton *)lockView;
    
    @weakify(self);
    /// 截屏按钮
    if(!self.config.hiddenCutScreenBtn){
        UIButton *cutScreenButton = [UIButton new];
        cutScreenButton.hidden = YES;
        self.cutScreenButton = cutScreenButton;
        [cutScreenButton setImage:HY_IMAGE_URL(@"icon_screenshot")
                         forState:UIControlStateNormal];
        [self.view addSubview:cutScreenButton];
        [cutScreenButton mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerX.mas_equalTo(lockView.mas_centerX);
            make.top.mas_equalTo(self.view.mas_centerY).mas_equalTo(10);
        }];
        RAC(self.cutScreenButton,hidden) = RACObserve(self.topToolBar, hidden);
        [[cutScreenButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
            @strongify(self);
            [self screenShot];
        }];
    }
}

// 引导手势
- (void)showGuideView
{
    if (![[[NSUserDefaults standardUserDefaults] objectForKey:@"EnterPlayer"] boolValue]) {
        [[UIApplication sharedApplication].keyWindow addSubview:self.guideView];
        [self.guideView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.mas_equalTo(0);
        }];
        [[NSUserDefaults standardUserDefaults] setValue:@(YES) forKey:@"EnterPlayer"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

- (void)bindPlayerSignal
{
    @weakify(self);
    RACChannelTerminal *channelA = RACChannelTo(self.bottomToolBar.slider.slider, progress);
    RACChannelTerminal *channelB = RACChannelTo(self.minBottomView.slider.slider, progress);
    [channelA subscribe:channelB];
    [channelB subscribe:channelA];
    
    self.minBottomView.playButton.rac_command = self.bottomToolBar.playButton.rac_command;
    self.minBottomView.qrCodeButton.rac_command = self.bottomToolBar.qrButton.rac_command;
    self.minBottomView.downloadButton.rac_command = self.bottomToolBar.downloadButton.rac_command;
    self.minBottomView.stretchButton.rac_command = self.bottomToolBar.stretchButton.rac_command;
    self.minBottomView.catalogButton.rac_command = self.bottomToolBar.catalogButton.rac_command;
    self.minBottomView.speedButton.rac_command = self.bottomToolBar.speedButton.rac_command;
    self.minBottomView.collectButton.rac_command = self.bottomToolBar.collectButton.rac_command;
    RAC(self.bottomToolBar.playButton, selected) = RACObserve(self.playerManager.player, playStauts);
    RAC(self.minBottomView.playButton, selected) = RACObserve(self.bottomToolBar.playButton, selected);
    RAC(self.minBottomView.currentTimeLabel, text) = [RACObserve(self.bottomToolBar.currentTimeLabel, text) skip:1];
    RAC(self.minBottomView.totalTimeLabel, text) = [RACObserve(self.bottomToolBar.totalTimeLabel, text) skip:1];
    RAC(self.bottomToolBar.slider.slider, state) = RACObserve(self.minBottomView.slider.slider, state);
    RAC(self.minBottomView.slider, cache) = RACObserve(self.bottomToolBar.slider, cache);
    RAC(self.minBottomView.slider, userInteractionEnabled) = RACObserve(self.bottomToolBar.slider, userInteractionEnabled);
    RAC(self.topToolBar.titleLabel,text) = [RACObserve(self.config, videoTitle) skip:1];
    RAC(self.bottomToolBar.collectButton,selected) = RACObserve(self.viewModel, isCollect);
    RAC(self.bottomToolBar.downloadButton,hidden) = RACObserve(self.config, isLocalVideo);
    RAC(self.bottomToolBar.qrButton,hidden) = RACObserve(self.config, isLocalVideo);
    RAC(self.minBottomView.qrCodeButton,hidden) = RACObserve(self.config, isLocalVideo);
    RAC(self.minBottomView.downloadButton,hidden) = RACObserve(self.config, isLocalVideo);
    RAC(self.minBottomView.collectButton,selected) = RACObserve(self.viewModel, isCollect);
    RAC(self.minBottomView,screen) = RACObserve(self.bottomToolBar, screen);
    
    [[RACObserve(self.playerManager.player, rate) distinctUntilChanged] subscribeNext:^(id x) {
        @strongify(self);
        NSString *speed = [NSString stringWithFormat:@"%.1f", [x floatValue]];
        [self.minBottomView.speedButton setTitle:speed forState:UIControlStateNormal];
        [self.bottomToolBar.speedButton setTitle:speed forState:UIControlStateNormal];
    }];
    [RACObserve(self, hiddMeunTime) subscribeNext:^(id x) {
        @strongify(self);
        if(self.hiddMeunTime==PLAY_MENU_HIDDEN_TIME){
            if([self isFull]){
                if (!self.topToolBar.hidden && !self.bottomToolBar.isDragging){
                    [self menuViewHidden:NO];
                }
            }else{
                if (!self.minBottomView.hidden && !self.minBottomView.isDragging) {
                    [self menuViewHidden:NO];
                }
            }
        }
    }];
    [[RACObserve(self.config, playIndex) skip:1] subscribeNext:^(id x) {
        @strongify(self);
        if(self.listView){
            self.listView.currentModel = self.config.currentVideoModel;
        }
        //播放完成后且自动播放下一个 如果有截图移除掉
        if (self.shareView) {
            [self removeShareView];
        }
    }];
}

- (void)addPlayerObserver
{
    @weakify(self);
    [[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil] takeUntil:self.rac_willDeallocSignal]filter:^BOOL(id value) {
        @strongify(self);
        return !self.isOpenPip;
    }] subscribeNext:^(id x) {
        @strongify(self);
        if(!self.config.isAudioMode){
            if(![HYMineSetManager shareManager].isAllowBackground){
                self.playerManager.playStateHold = YES;
                // 保存播放记录
                [self savePlayRecord];
            }
        }
    }];
    
    [[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationWillEnterForegroundNotification object:nil] takeUntil:self.rac_willDeallocSignal] filter:^BOOL(id value) {
        @strongify(self);
        return !self.isOpenPip;
    }] subscribeNext:^(id x) {
        @strongify(self);
        if(!self.config.isAudioMode){
            if(![HYMineSetManager shareManager].isAllowBackground){
                self.playerManager.playStateHold = NO;
            }
        }
    }];
    
    RACSignal *appearSignal = [[[self rac_signalForSelector:@selector(viewWillAppear:)] skip:self.config.isBasePlayer?1:0] map:^id(id value) {
        return @(YES);
    }];
    
    RACSignal *disappearSignal = [[[self rac_signalForSelector:@selector(viewWillDisappear:)] map:^id(id value) {
        return @(NO);
    }] filter:^BOOL(id value) {
        @strongify(self);
        return !self.isOpenPip;
    }];
    [[appearSignal merge:disappearSignal] subscribeNext:^(id x) {
        @strongify(self);
        if(!self.config.isAudioMode){
            self.playerManager.playStateHold = ![x boolValue];
        }
    }];
}

- (void)autoPlay
{
    if(self.viewModel){
        [self.viewModel readyToPlay];
    }else{
        NSString *videoUrl = [self.config fetchCurrentVideoUrl];
        if(videoUrl.length){
            self.playerManager.currentVideoUrl = videoUrl;
        }
    }
}

#pragma mark - action
- (void)minBackBtnAction
{
    [self stop];
    if(self.mainScorllView){
        [self.mainScorllView removeFromSuperview];
        self.mainScorllView = nil;
    }
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - 截屏
- (void)screenShot
{
    [HYHub show];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSString *cachesDir = NSTemporaryDirectory();
        cachesDir = [NSString stringWithFormat:@"%@/videoSnapShot.png",cachesDir];
        UIImage *shotImage = [self.playerManager cutAssignTimeVideoImage];
        //旋转图片方向 0 横屏 1 竖屏 2正方形
        NSInteger imageShowType = 2;
        if(shotImage.size.width > shotImage.size.height){
            imageShowType = 0;
        }else{
            imageShowType = 1;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            if(shotImage){
                /// 判断相册权限
                [self showScreenShotImage:shotImage showType:imageShowType];
                if([HYMineSetManager shareManager].isAllowScreenShotSavePhoto){
                    if([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized){
                        UIImageWriteToSavedPhotosAlbum(shotImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
                    }else{
                        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                            if(status == PHAuthorizationStatusAuthorized){
                                UIImageWriteToSavedPhotosAlbum(shotImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
                            }
                        }];
                    }
                }else{
                    [HYHub dismiss];
                }
            }else{
                [HYHub showMessage:NSLocalizedString(@"截屏失败，请稍后重试", nil)];
            }
        });
    });
}

#pragma mark - 目录
- (void)showVideoList
{
    HYVideoListView *listView = [[HYVideoListView alloc]initWithCurrentVideoModel:self.config.currentVideoModel
                                                                       videoLists:self.config.videoSoucres
                                                                           isFull:[self isFull]];
    listView.delegate = self;
    [listView showView:self.config.isAudioMode?[UIApplication sharedApplication].keyWindow:self.view];
    self.listView = listView;
}

#pragma mark - HYVideoListViewDelegate
- (void)changeVideoWithIndexPath:(NSInteger)index
{
    [self savePlayRecord];
    if(self.mainScorllView){
        if(index == 0 && self.config.videoSoucres.count == 2){//防止图片遮罩不消失问题
            [self.mainScorllView.mainScrollView setContentOffset:CGPointMake(0, 0)];
        }else{
            [self.mainScorllView setCurPage:index];
        }
    }else{
        [self.viewModel changePlayIndex:index];
    }
}

- (void)dismiss
{
    [self.listView removeFromSuperview];
    self.listView = nil;
}

- (void)showScreenShotImage:(UIImage *)image showType:(NSInteger)showType
{
    @weakify(self);
    HYVideoScreenShotShareView *shareView = [[HYVideoScreenShotShareView alloc]initWithScreenShotImage:image
                                                                                              showType:showType
                                                                                            shareBlock:^{
        @strongify(self);
        [self shareImageInfo:image];
        [self removeShareView];
    } closeBlock:^{
        @strongify(self);
        [self removeShareView];
    }];
    self.shareView = shareView;
    [shareView showSuperView:self.view];
}

- (void)shareImageInfo:(UIImage *)image
{
    //分享的图片
    UIImage *imageToShare = image;
    NSArray *activityItems = @[imageToShare];
    
    HYActivity *activity = [[HYActivity alloc]initWithTitle:@"" withActivityImage:imageToShare withUrl:@"" withShareContext:activityItems];
    NSArray *activitys = @[activity];
    
    UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:activitys];
    
    activityVC.excludedActivityTypes = @[];
    [self presentViewController:activityVC animated:YES completion:nil];
    // 分享之后的回调
    activityVC.completionWithItemsHandler = ^(UIActivityType  _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {
        if (completed) {
            //分享成功
            [HYHub showMessage:NSLocalizedString(@"分享成功", nil)];
        } else  {
            [HYHub showMessage:NSLocalizedString(@"分享失败", nil)];
        }
    };
}
- (void)removeShareView
{
    [self.shareView removeFromSuperview];
    self.shareView = nil;
}

-(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    NSString *msg = nil;
    if(error){
        msg = NSLocalizedString(@"截屏失败，请稍后重试", nil) ;
    }else{
        msg = NSLocalizedString(@"截屏成功，已保存至相册", nil) ;
    }
    [HYHub showMessage:msg];
    //将缓存文件删除
    NSString *path = [NSString stringWithFormat:@"%@/videoSnapShot.png",NSTemporaryDirectory()];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtPath:path error:nil];
}

#pragma mark - 展示二维码
- (void)showQrCodeImage
{
    self.playerManager.playStateHold = YES;
    @weakify(self);
    HYShowQRCodeView *QRCodeView = [[HYShowQRCodeView alloc]initWithFileName:self.config.fetchCurrentVideoTitle
                                                                     linkUrl:self.config.fetchCurrentVideoUrl
                                                                      isFull:[self isFull] disappear:^{
        @strongify(self);
        self.playerManager.playStateHold = NO;
    }];
    [QRCodeView showInView:self.view];
}

#pragma mark - airplay
- (void)registerNotification
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteHasChangedNotification:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
}

- (void)audioRouteHasChangedNotification:(NSNotification *)notification
{
    NSString *airplayDeviceName = [self activeAirplayOutputRouteName];
    self.isAirPlay = airplayDeviceName.length > 0;
    if(self.isAirPlay){
        [self.playerManager.playerView showTipView:NSLocalizedString(@"airPlay投屏中", nil) delay:0];
    }else{
        [self.playerManager.playerView hiddenTipView];
    }
}

//遍历当前设备所有通道.返回isEqualToString:AVAudioSessionPortAirPlay通道的具体名称,如果名称不为nil则为当前连接到了AirPlay
- (NSString*)activeAirplayOutputRouteName
{
    AVAudioSession* audioSession = [AVAudioSession sharedInstance];
    AVAudioSessionRouteDescription* currentRoute = audioSession.currentRoute;
    for (AVAudioSessionPortDescription* outputPort in currentRoute.outputs){
        if ([outputPort.portType isEqualToString:AVAudioSessionPortAirPlay])
            return outputPort.portName;
    }
    return nil;
}

#pragma mark - 开始搜索投屏设备
- (void)startToSearchDevice
{
    if ([[HYNetWorkManager shareManager] currentReachabilityStatus] != ReachableViaWiFi) {
        [HYHub showMessage:NSLocalizedString(@"请连接WI-FI环境，需要手机与设备连接相同的网络", nil)];
        return;
    }
    if ([HYDLNA sharedHYDLNAManager].lastConnectDevice && !self.isStartPs) {
        self.device = [HYDLNA sharedHYDLNAManager].lastConnectDevice;
        [self startDLNA];
    }else{
        PSSearchViewController *vc = [PSSearchViewController new];
        vc.hidesBottomBarWhenPushed = YES;
        [self.navigationController pushViewController:vc animated:YES];
        @weakify(self);
        [vc choosePSDeviceBlock:^(RACTuple * _Nonnull tuple) {
            @strongify(self);
            self.device = tuple.first;
            [self startDLNA];
        }];
    }
}

#pragma mark - 开始投屏
- (void)startDLNA
{
    @weakify(self);
    if(self.psCoverView){
        [self.psCoverView changeDeviceName:self.device.friendlyName];
    }else{
        self.isLocked = YES;
        [self stop];
        self.config.currentVideoModel.isSelect = YES;
        self.psCoverView = [[PSCoverView alloc]initWithDeviceName:self.device.friendlyName
                                                changeDeviceBlock:^{
            @strongify(self);
            [self startToSearchDevice];
        } closeBlock:^{
            @strongify(self);
            [self closeDLNA];
        }];
        [self.view addSubview:self.psCoverView];
        [self.psCoverView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.center.equalTo(self.view);
            make.width.mas_equalTo(kScreenWidth);
            make.height.mas_equalTo(kScreenWidth*9/16);
        }];
        [self.view bringSubviewToFront:self.minBottomView];
        /// 监听系统音量变化
        [[AVAudioSession sharedInstance] addObserver:self forKeyPath:@"outputVolume" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:(void *)[AVAudioSession sharedInstance]];
        // 投屏成功
        [HYDLNA sharedHYDLNAManager].dlnaStartPlay = ^(){
            @strongify(self);
            self.isStartPs = YES;
            [self.playerManager.playerView showTipView:NSLocalizedString(@"airPlay投屏中", nil) delay:0];
        };
        // 投屏时间回调
        [HYDLNA sharedHYDLNAManager].playTimerBlock = ^(NSInteger playTime) {
            @strongify(self);
            if ([HYDLNA sharedHYDLNAManager].lastTime > 0) {
                [[HYDLNA sharedHYDLNAManager] seekChanged:[HYDLNA sharedHYDLNAManager].lastTime];
                [HYDLNA sharedHYDLNAManager].lastTime = 0;
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                self.bottomToolBar.playingTime = playTime;
                if ([HYDLNA sharedHYDLNAManager].progress > 0.0) {
                    self.bottomToolBar.slider.slider.progress = [HYDLNA sharedHYDLNAManager].progress;
                }
            });
        };
        // 投屏暂停播放回调
        [HYDLNA sharedHYDLNAManager].dlnaPauseBlock = ^(){
            @strongify(self);
            dispatch_async(dispatch_get_main_queue(), ^{
                self.minBottomView.playButton.selected = [HYDLNA sharedHYDLNAManager].isPlaying;
            });
        };
    }
    [self startDLNAWithSeekTime:self.bottomToolBar.playingTime updatePlayUrl:NO changeDevice:self.isStartPs?YES:NO];
    
}

- (void)startDLNAWithSeekTime:(NSInteger)seekTime updatePlayUrl:(BOOL)needUpdate changeDevice:(BOOL)changeDevice
{
    if (changeDevice) {
        [[HYDLNA sharedHYDLNAManager].render stop];
        [HYDLNA sharedHYDLNAManager].lastTime = seekTime;
        [[HYDLNA sharedHYDLNAManager] startDLNAWithURL:[self.config fetchCurrentVideoUrl] device:self.device];
    }else{
        if ([HYDLNA sharedHYDLNAManager].isPlaying) {
            if (needUpdate) {
                [HYDLNA sharedHYDLNAManager].lastTime = seekTime;
                [[HYDLNA sharedHYDLNAManager] playTheURL:[self.config fetchCurrentVideoUrl]];
            }else{
                [[HYDLNA sharedHYDLNAManager] seekChanged:seekTime];
            }
        }else{
            [HYDLNA sharedHYDLNAManager].lastTime = seekTime;
            [[HYDLNA sharedHYDLNAManager] startDLNAWithURL:[self.config fetchCurrentVideoUrl] device:self.device];
        }
    }
}

#pragma mark - 关闭投屏
- (void)closeDLNA
{
    [[HYDLNA sharedHYDLNAManager] endDLNA];
    [[AVAudioSession sharedInstance] removeObserver:self forKeyPath:@"outputVolume" context:(void *)[AVAudioSession sharedInstance]];
    [self.navigationController popViewControllerAnimated:YES];
}


#pragma mark - 屏幕是否支持自动转屏
- (BOOL)hy_supportToScreenStatus
{
    return self.isLocked?NO:![HYVideoLockView hy_Lock_View];
}

#pragma mark - 全屏
- (void)fullBtnAction
{
    [self fullShowVideo:YES];
}

/// 视频全屏
- (void)fullShowVideo:(BOOL)isFull
{
    [self hy_rotateFull:isFull];
}
/// 停止播放
- (void)stop
{
    // 保存播放记录
    if(!self.config.isCancelPlayHistory){
        [self savePlayRecord];
        [HYPreviewHistoryManager updateLearnHistoy];
    }
    
    [self.config cancelSelectStatus];
    if(self.playTimer){
        [self.playTimer invalidate];
        self.playTimer = nil;
    }
    [self.playerManager stop];
}

- (void)removeTimer
{
    if(self.playTimer){
        [self.playTimer invalidate];
        self.playTimer = nil;
    }
}

/// 是否是全屏
- (BOOL)isFull
{
    UIInterfaceOrientation orientation;
    if (@available(iOS 13.0, *)) {
        orientation = [UIApplication sharedApplication].windows.firstObject.windowScene.interfaceOrientation;
    }else{
        orientation = [UIApplication sharedApplication].statusBarOrientation;
    }
    return  orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight;
}

#pragma mark - HY_Auto_Rotate_Delegate
- (void)hy_autoRotateFull:(BOOL)full
{
    [HYAlertShowAnimate disappear];
    // 设置菜单栏显隐
    [self menuViewHidden:!self.topToolBar.hidden];
    
    if (full) {
        [self.playerManager.playerView removeFromSuperview];
        [self.view insertSubview:self.playerManager.playerView atIndex:0];
        [self.playerManager.playerView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.view);
        }];
        [self.mainScorllView removeFromSuperview];
        self.mainScorllView = nil;
    } else {
        [self addScrollViewPlayView];
        [HYVideoLockView setFilterNoHiddenView:self.mainScorllView];
    }
    [self.topToolBar changeScreen:full];
    [self.topToolBar mas_updateConstraints:^(MASConstraintMaker *make) {
        make.height.mas_equalTo(full?64:68+STATUS_BAR_HEIGHT);
    }];
}

#pragma mark - 显示/隐藏菜单，YES显示/NO隐藏
- (void)menuViewHidden:(BOOL)show
{
    CLog(@"menuViewHidden -- %d",show);
    
    CATransition *topAnimation = [CATransition animation];
    topAnimation.duration = 0.35;
    topAnimation.type = kCATransitionPush;
    topAnimation.subtype = kCATransitionFromTop;
    topAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    CATransition *bottomAnimation = [CATransition animation];
    bottomAnimation.duration = 0.35;
    bottomAnimation.type = kCATransitionPush;
    bottomAnimation.subtype = kCATransitionFromBottom;
    bottomAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    /// 横屏
    if(show){
        [self.topToolBar.layer addAnimation:bottomAnimation forKey:@"animation"];
        [self.minBottomView.layer addAnimation:topAnimation forKey:@"animation"];
        [self.bottomToolBar.layer addAnimation:topAnimation forKey:@"animation"];
    }else{
        [self.topToolBar.layer addAnimation:topAnimation forKey:@"animation"];
        [self.minBottomView.layer addAnimation:bottomAnimation forKey:@"animation"];
        [self.bottomToolBar.layer addAnimation:bottomAnimation forKey:@"animation"];
    }
    if(self.isAirPlay){
        self.minBottomView.hidden = [self isFull]?YES:NO;
    }else{
        self.minBottomView.hidden = [self isFull]?YES:(!show);
    }
    
    self.topToolBar.hidden = !show;
    
    if(self.isAirPlay){
        self.bottomToolBar.hidden = [self isFull]?NO:YES;
    }else{
        self.bottomToolBar.hidden = [self isFull]?(!show):YES;
    }
}

#pragma mark - 返回小屏
- (void)backMin
{
    [self hy_rotateFull:NO];
}

- (void)waitBackMin:(dispatch_block_t)done
{
    if ([self isFull]) {
        self.view.userInteractionEnabled = NO;
        @weakify(self);
        [[[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidChangeStatusBarOrientationNotification
                                                                  object:nil] take:1] delay:.5]
          takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) {
            @strongify(self);
            self.view.userInteractionEnabled = YES;
            done();
        }];
        [self backMin];
    } else {
        done();
    }
}

#pragma mark - 画中画
- (void)startPip
{
    if([self.playerManager startPip]){
        [HYHub show];
    }
}

#pragma mark - 使用画中画播放
- (void)usePipPlayer
{
    @weakify(self);
    [self coverPlayerView:self.pipBgView addObserver:YES];
    [[self rac_signalForSelector:@selector(viewDidAppear:)] subscribeNext:^(id x) {
        @strongify(self);
        [self.pipBgView removeFromSuperview];
        self.pipBgView = nil;
    }];
    
    [self waitBackMin:^{
        @strongify(self);
        [PictureInPictureManager savePipVc:self portrait:![self isFull]];
        [self.navigationController popViewControllerAnimated:YES];
    }];
}

#pragma mark - 从画中画恢复播放
- (void)pipRecoverPlayer
{
    if(![self.playerManager.player isPlaying]){
        if(self.playerManager.playStatus){// 播放状态中停止，立即重新播放
            [self.playerManager.player hy_playImmediatelyAtRate:self.playerManager.rate];
        }
    }
}

- (void)coverPlayerView:(UIView *)coverView addObserver:(BOOL)addObserver
{
    [self.view addSubview:coverView];
    [self.view insertSubview:coverView belowSubview:self.topToolBar];
    [coverView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(0);
    }];
    
    if (addObserver) {
        @weakify(self, coverView);
        [[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidChangeStatusBarOrientationNotification
                                                                 object:nil]
           takeUntil:self.rac_willDeallocSignal] takeUntil:[coverView rac_signalForSelector:@selector(removeFromSuperview)]]
         subscribeNext:^(id x) {
            @strongify(self, coverView);
            [self coverPlayerView:coverView addObserver:NO];
        }];
    }
}

- (void)playingTimer
{
    self.hiddMeunTime ++;
}

#pragma mark - HYPlayerHandleProtocol

/// 设置当前视频总时长，在将要可以播放的时候调用
- (void)currentVideoTotalTime:(NSInteger)total
{
    CLog(@"视频总时长：total -- %ld",total);
    self.bottomToolBar.totalTime = total;
}

#pragma mark - 播放状态改变
- (void)playerItemStatusBefore:(HYBasePlayerStatus)playerStatus
                         error:(NSError *)error
                        failed:(NSString *)failed
{
    if(playerStatus == HYBasePlayerStatusReadyToPlay){
        if(!self.playTimer){
            self.minBottomView.hidden = [self isFull];
            self.playTimer = [NSTimer scheduledTimerWithTimeInterval:1.
                                                              target:self
                                                            selector:@selector(playingTimer)
                                                            userInfo:nil
                                                             repeats:YES];
            [[NSRunLoop currentRunLoop] addTimer:self.playTimer forMode:NSRunLoopCommonModes];
            [self.playTimer fire];
        }
        if(self.mainScorllView){
            UIView *contentView = [self.mainScorllView getCurrentShowView];
            UIImageView *coverView = [contentView viewWithTag:1000];
            coverView.hidden = YES;
            [contentView bringSubviewToFront:self.playerManager.playerView];
        }
    }else if (playerStatus == HYPlayerStatusFailed){
        if(self.config.isAudioMode){
            [HYHub showMessage:NSLocalizedString(@"不支持此媒体的格式", nil)];
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self playNextVideo:NO];
            });
        }else{
            if(self.mainScorllView){
                UIView *contentView = [self.mainScorllView getCurrentShowView];
                UIImageView *coverView = [contentView viewWithTag:1000];
                coverView.hidden = YES;
            }
        }
    }
}

// 获取播放记忆点
- (CGFloat)currentVideoHistory
{
    if(self.config.isCancelPlayHistory){
        return 0;
    }
    return [self.viewModel currentVideoHistory];
}

// 播放完成
- (void)videoPlayerDone
{
    if([HYMineSetManager shareManager].isAutoPlayNext){
        [self playNextVideo:YES];
    }else{
        [self.playerManager againPlayVideo];
    }
}

// 切换视频
- (void)playLastVideo
{
    // 保存播放记录
    [self savePlayRecord];
    if(self.viewModel){
        if(![self.viewModel playLast]){
            [HYHub showMessage:NSLocalizedString(@"到顶了", nil)];
        }
    }else{
        if([self.config playLast]){
            [self.playerManager replaceVideoUrl:[self.config fetchCurrentVideoUrl]];
        }else{
            [HYHub showMessage:NSLocalizedString(@"到顶了", nil)];
        }
    }
}

- (void)playNextVideo:(BOOL)isDone
{
    // 保存播放记录
    [self savePlayRecord];
    
    if(self.config.playMode == HYVideoPlayOrderMode_default || !isDone){
        if(self.viewModel){
            if(self.mainScorllView){
                NSInteger nextIndx = [self.config fetchNextPlayIndex];
                if(nextIndx){
                    [self.mainScorllView setCurPage:nextIndx];
                }else{
                    [HYHub showMessage:NSLocalizedString(@"全部播放完成", nil)];
                }
            }else{
                if(![self.viewModel playNext]){
                    if(isDone){
                        [self.playerManager playDone];
                    }else{
                        [HYHub showMessage:NSLocalizedString(@"全部播放完成", nil)];
                    }
                }
            }
        }else{
            if([self.config playNext]){
                [self.playerManager replaceVideoUrl:[self.config fetchCurrentVideoUrl]];
            }else{
                if(isDone){
                    [self.playerManager playDone];
                }else{
                    [HYHub showMessage:NSLocalizedString(@"全部播放完成", nil)];
                }
            }
        }
    }else{
        if(self.config.playMode == HYVideoPlayOrderMode_loop){
            [self.playerManager againPlayVideo];
        }else{
            if([self.config randomPlay]){
                [self.playerManager replaceVideoUrl:[self.config fetchCurrentVideoUrl]];
            }
        }
    }
}

- (void)savePlayRecord
{
    // 保存播放记录
    if(!self.config.isCancelPlayHistory){
        // 正常播放才做播放记录的保存
        if(self.playerManager.player.normalPlaying){
            [self.viewModel saveCurrentVideoPlayTime:self.playerManager.player.hy_currentTime 
                                          isPlayDone:self.playerManager.playComplete];
        }
    }
}

/// 重新播放
- (void)againPlay
{
    [self.playerManager replaceVideoUrl:[self.config fetchCurrentVideoUrl]];
}

/// 播放器实时回调当前时间
- (void)playerCurrentTime:(CGFloat)currentTime
                totalTime:(CGFloat)totalTime
{
    self.bottomToolBar.playingTime = currentTime;
    CGFloat cacheTime = self.config.isLocalVideo?ceilf(totalTime):[self.playerManager.player hy_cacheProgress];
    self.bottomToolBar.cacheTime = cacheTime;
    // 后台播放显示信息
    [self.playerManager configNowPlayingInfoPlayTitle:[self.config fetchCurrentVideoTitle] currentTime:currentTime totalTime:totalTime];
}

/// 单击播放视频view
- (void)singleClickPlayVideoView
{
    self.hiddMeunTime = 0;
    [self menuViewHidden:self.topToolBar.hidden];
}

/// 双击播放视频view
- (void)doubleClickPlayVideoView
{
    self.hiddMeunTime = 0;
    self.playerManager.playStateHold = self.playerManager.playStatus?YES:NO;
}

/// 倍速发生变化
- (void)playerRateChanged:(CGFloat)rate
{
    // 画中画倍速为0时，设置为暂停状态
    if(self.isOpenPip && ![PictureInPictureManager sharedInstance].recover){
        if(!rate){
            [self.playerManager pause];
        }else{
            [self.playerManager play];
        }
    }
}

- (void)pictureInPicturePlayBackStatus:(HYPipPlayBackStatus)pipStatus
{
    if(pipStatus == HYPipPlayBackStatusDidStart) {
        [HYHub dismiss];
        self.isOpenPip = YES;
        [self usePipPlayer];
    }else if (pipStatus == HYPlayerPipStatusRestore) {
        [PictureInPictureManager open];
    }else if (pipStatus == HYPipPlayBackStatusDidStop) {
        if(self.isOpenPip){
            [self pipRecoverPlayer];
            self.isOpenPip = NO;
        }
        [PictureInPictureManager closePip];
    }else if (pipStatus == HYPipPlayBackStatusFailed){
        self.isOpenPip = NO;
        [HYHub showMessage:NSLocalizedString(@"开启画中画失败", nil)];
    }
}

#pragma mark - 蓝牙耳机控制
- (void)HSPControlRemoteChangeTrack:(BOOL)nextTrack
{
    if(nextTrack){
        [self playNextVideo:NO];
    }else{
        [self playLastVideo];
    }
}

/// 当前是暂停状态，滑动屏幕跳转时间点的时候，通知ui也进行改变
- (void)progressSlideChange:(CGFloat)time
{
    self.bottomToolBar.playingTime = time;
}

#pragma mark - 系统声音改变
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if(self.isStartPs){
        if(context == (__bridge void *)[AVAudioSession sharedInstance]){
            float newValue = [[change objectForKey:@"new"] floatValue];
            [[HYDLNA sharedHYDLNAManager] volumeChanged:[NSString stringWithFormat:@"%f",100*newValue]];
        }
    }
}

- (void)changeAudioWithPlayUrl:(NSString *)playUrl
{
    [self.playerManager replaceVideoUrl:playUrl];
}

#pragma mark - loadLazy

- (HYVideoPlayerManager *)playerManager
{
    if(!_playerManager){
        _playerManager = [[HYVideoPlayerManager alloc]initWithDelegate:self];
        _playerManager.isBasePlayer = self.config.isBasePlayer;
    }
    return _playerManager;
}

/// 倍速
- (HYPlayerSpeedView *)speedView
{
    if (!_speedView) {
        _speedView = [[HYPlayerSpeedView alloc] init:self.playerManager
                                           textColor:App_SelectLightColor
                                                full:[self isFull]];
        [self.view addSubview:_speedView];
        [_speedView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.mas_equalTo(0);
        }];
        @weakify(self);
        [[[RACObserve(_speedView, hidden) skip:1] filter:^BOOL(id value) {
            return [value boolValue] == YES;
        }] subscribeNext:^(id x) {
            @strongify(self);
            [self.speedView removeFromSuperview];
            self.speedView = nil;
        }];
    }
    return _speedView;
}

- (HYVideoSpeedBottomView *)speedBottomView
{
    if(!_speedBottomView){
        @weakify(self);
        _speedBottomView = [[HYVideoSpeedBottomView alloc]initWithCurrentSpeed:self.playerManager.rate
                                                                    speedBlock:^(CGFloat speed) {
            @strongify(self);
            self.playerManager.rate = speed;
        } disappear:^{
            @strongify(self);
            [self.speedBottomView removeFromSuperview];
            self.speedBottomView = nil;
        }];
    }
    return _speedBottomView;
}

- (HYSimplePlayerGuideView *)guideView
{
    if(!_guideView){
        @weakify(self);
        _guideView = [[HYSimplePlayerGuideView alloc]initWithTouchBlock:^{
            @strongify(self);
            [self.guideView removeFromSuperview];
            self.guideView = nil;
        }];
    }
    return _guideView;
}

@end
